package se.webbzon.boltzmann.editor.factory.propertyframe;

import java.util.Collection;
import java.util.SortedSet;

import se.webbzon.boltzmann.editor.component.appearance.SimpleAppearancePanel;
import se.webbzon.boltzmann.editor.component.geometry.GeometryPanel;
import se.webbzon.boltzmann.editor.component.texturelist.TextureSetEntry;
import se.webbzon.boltzmann.editor.component.texturelist.TextureSetList;
import se.webbzon.boltzmann.editor.mvc.EditorModel;
import se.webbzon.boltzmann.editor.propertyframe.WorldObjectPropertyFrame;
import se.webbzon.boltzmann.editor.propertyframe.WorldStaticObjectPropertyFrame;
import se.webbzon.boltzmann.object.geometry.Geometry;
import se.webbzon.boltzmann.object.geometry.GeometryAppearance;
import se.webbzon.boltzmann.object.geometry.GeometryMask;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.appearance.Appearance3DException;

public class GeometryPropertyFrameFactory implements PropertyFrameFactory {
	
	// A sorted set of all the available textures
	private SortedSet<TextureSetEntry> textures;
	
	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new GeometryPropertyFrameFactory by using a given
	 * sorted set of available textures. **/
	public GeometryPropertyFrameFactory(SortedSet<TextureSetEntry> textures) {
		this.textures = textures;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	@Override public String getWorldObjectName() {
		return Geometry.worldObjectName;
	}

	@Override public WorldObjectPropertyFrame makePropertyFrame(EditorModel model,
																WorldObject instance) {
		return new PropertyFrameImpl(textures,model,(Geometry) instance);
	}
	
	/*============================================================
	Private Classes
	============================================================*/
	
	/** An implementation of a property frame. **/
	private static final class PropertyFrameImpl extends WorldStaticObjectPropertyFrame {
	
		// The geometry appearance property panel
		private final GeometryPanel geometryAppearance, geometryMask;
		
		// The simple appearance property panel
		private final SimpleAppearancePanel appearancePanel;
		
		// The texture property panel
		private final TextureSetList texturePanel;
	
		/*============================================================
		Constructors
		============================================================*/
	
		public PropertyFrameImpl(	SortedSet<TextureSetEntry> textures,
									EditorModel model, Geometry g) {
			super(model,g);
		
			// Create geometry appearance panel
			final GeometryAppearance appearance = g.getGeometryAppearance();
			geometryAppearance = new GeometryPanel(	appearance.getGeometry(),
													appearance.isOpen(),
													appearance.getDivisions(),
													appearance.isBackfaced());
			addPanel("Geometry Appearance",geometryAppearance);
			
			// Create geometry mask panel
			final GeometryMask mask = g.getGeometryMask();
			geometryMask = new GeometryPanel(	mask.getGeometry(),
												mask.isOpen(),
												mask.getDivisions());
			addPanel("Geometry Mask",geometryMask);
		
			// Create appearance panel
			appearancePanel = new SimpleAppearancePanel(appearance.getAppearance());
			addPanel(appearancePanel.getName(),appearancePanel);
			
			// Create texture panel
			texturePanel = new TextureSetList(	textures,
												appearance.getTextureSetName(),
												appearance.getAppearance().getTextureIndex(),
												appearance.getAppearance().getTextureSpeed());
			addPanel(texturePanel.getName(),texturePanel);
			initialize();
		}
	
		/*============================================================
		Public Methods
		============================================================*/
	
		public boolean apply(Collection<String> errorMessages) {
			if (super.apply(errorMessages)) try {
				Geometry g = (Geometry) getInstance();
				GeometryMask mask = new GeometryMask(	geometryMask.getGeometry(),
														geometryMask.isOpen(),
														geometryMask.getDivisions());
				GeometryAppearance appearance = 
						new GeometryAppearance(	geometryAppearance.getGeometry(),
												geometryAppearance.isOpen(),
												geometryAppearance.getDivisions(),
												geometryAppearance.isBackfaced(),
												appearancePanel.getRenderingOrder(),
												texturePanel.getTextureSetName(),
												texturePanel.getTextureIndex(),
												texturePanel.getTextureSpeed(),
												appearancePanel.getXLayer(),
												appearancePanel.getYLayer(),
												appearancePanel.getZLayer(),
												appearancePanel.getColor(),
												appearancePanel.getTransparency(),
												appearancePanel.getHRep(),
												appearancePanel.getVRep(),
												appearancePanel.getHOffset(),
												appearancePanel.getVOffset(),
												appearancePanel.getRotation());
				appearance.getAppearance().setTextureIndex(texturePanel.getTextureIndex());
				appearance.getAppearance().setTextureIndex(texturePanel.getTextureSpeed());
				g.setGeometryMask(mask);
				g.setGeometryAppearance(appearance);
				return true;
			} catch (NumberFormatException | Appearance3DException e) {
				errorMessages.add(e.getMessage());
				return false;
			} else
				return false;
		}
	
	}
	
}



